package com.lhcz.service.service.facedata.impl;


import com.alibaba.fastjson.JSONObject;
import com.lhcz.aop.log.ALog;
import com.lhcz.model.Log;
import com.lhcz.service.service.LogService;
import com.lhcz.service.service.facedata.dto.LogEntity;
import com.lhcz.service.service.facedata.dto.LogQueryCriteria;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


@Service
public class LogServiceImpl implements LogService {

    private static final String DATE_TIME = "yyyy-MM-dd HH:mm:ss";
    private final RestHighLevelClient restHighLevelClient;

    @Autowired
    public LogServiceImpl(RestHighLevelClient restHighLevelClient) {
        this.restHighLevelClient = restHighLevelClient;
    }


    @Override
    public Object queryAll(LogQueryCriteria criteria) throws IOException {
        SearchRequest searchRequest = new SearchRequest("sys_log");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//        sourceBuilder.from(pageable.getPageNumber());
//        sourceBuilder.size(pageable.getPageSize());
        sourceBuilder.sort(new FieldSortBuilder("createDate").order(SortOrder.DESC));
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        if (StringUtils.isEmpty(criteria.getDescription())) {
            queryBuilder.must(QueryBuilders.wildcardQuery("description", "*" + criteria.getDescription() + "*"));
        }
        if (StringUtils.isEmpty(criteria.getParams())) {
            queryBuilder.must(QueryBuilders.wildcardQuery("params", "*" + criteria.getParams() + "*"));
        }
        if (StringUtils.isEmpty(criteria.getUsername())) {
            queryBuilder.must(QueryBuilders.termQuery("username", criteria.getUsername()));
        }
        if (StringUtils.isEmpty(criteria.getRequestIp())) {
            queryBuilder.must(QueryBuilders.termQuery("requestIp", criteria.getRequestIp()));
        }
        if (StringUtils.isEmpty(criteria.getStartTime())) {
            // gte >=
            queryBuilder.must(QueryBuilders.rangeQuery("createDate").gte(criteria.getStartTime()));
        }
        if (StringUtils.isEmpty(criteria.getEndTime())) {
            // lte <=
            queryBuilder.must(QueryBuilders.rangeQuery("createDate").lte(criteria.getEndTime()));
        }

        sourceBuilder.query(queryBuilder);
        System.out.println("queryBuilder = " + queryBuilder);
        searchRequest.source(sourceBuilder);
        System.out.println("searchRequest = " + searchRequest);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHit[] searchHits = searchResponse.getHits().getHits();
        List<LogEntity> logEntities = new ArrayList<>();
        for (SearchHit hit : searchHits) {
            String sourceAsString = hit.getSourceAsString();
            LogEntity log = JSONObject.parseObject(sourceAsString, LogEntity.class);
            logEntities.add(log);
        }

        return logEntities;
    }


    @Override
    public void save(String username, String browser, String ip, ProceedingJoinPoint joinPoint, Log log) throws IOException {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        ALog aopLog = method.getAnnotation(ALog.class);
        // 方法路径
        String methodName = joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()";
        // 描述
        if (log != null) {
            log.setDescription(aopLog.value());
        }
        assert log != null;
        log.setRequestIp(ip);
        log.setAddress("内网");
        log.setMethod(methodName);
        log.setUsername(username);
        log.setParams(JSONObject.toJSONString(joinPoint.getArgs()));
        log.setBrowser(browser);
        log.setCreateDate(new Date());
        IndexRequest request = new IndexRequest("sys_log");
        request.id();


        String str = JSONObject.toJSONStringWithDateFormat(log, DATE_TIME);

        System.out.println("str = " + str);
        request.source(str, XContentType.JSON);
        restHighLevelClient.index(request, RequestOptions.DEFAULT);
    }

    @Override
    public Object findByErrDetail(Long id) {
        return null;
    }


}
